From c103cbec8acaab3e9259aae87c802573b584527c Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Tue, 21 Oct 2008 20:31:05 +0000 Subject: [PATCH] Bug 557266 - Window Management Problem 2008-10-21 Tor Lillqvist Bug 557266 - Window Management Problem Also reported in mail to gtk-list, and of course it has been well known in general that window state management is messy and buggy in various ways in gdk/win32. * gdk/win32/gdkwindow-win32.c (show_window_internal): Correct handling of GDK_WINDOW_STATE_ABOVE windows. It doesn't work to set the WS_EX_TOPMOST extended style bit using SetWindowLong(). We must call SetWindowPos() on the window using HWND_TOPMOST instead. The description for WS_EX_TOPMOST in the documentation for CreateWindowEx() even implies that if you read it carefully. svn path=/trunk/; revision=21694 --- ChangeLog | 15 ++++++++++++++ gdk/win32/gdkwindow-win32.c | 39 +++++++++++++++++++++++-------------- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 79e8e19c84..827bbb1db2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2008-10-21 Tor Lillqvist + + Bug 557266 - Window Management Problem + + Also reported in mail to gtk-list, and of course it has been well + known in general that window state management is messy and buggy + in various ways in gdk/win32. + + * gdk/win32/gdkwindow-win32.c (show_window_internal): Correct + handling of GDK_WINDOW_STATE_ABOVE windows. It doesn't work to set + the WS_EX_TOPMOST extended style bit using SetWindowLong(). We + must call SetWindowPos() on the window using HWND_TOPMOST + instead. The description for WS_EX_TOPMOST in the documentation + for CreateWindowEx() even implies that if you read it carefully. + 2008-10-21 Michael Natterer * gdk/gdkapplaunchcontext.c: reorder functions to be in standard diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index 14f5129a2c..340cc2a063 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -1028,6 +1028,8 @@ show_window_internal (GdkWindow *window, GdkWindowObject *private; HWND old_active_window; gboolean focus_on_map = TRUE; + DWORD exstyle; + HWND top; private = (GdkWindowObject *) window; @@ -1078,35 +1080,38 @@ show_window_internal (GdkWindow *window, focus_on_map = private->focus_on_map; } + exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE); + + if (private->state & GDK_WINDOW_STATE_BELOW) + exstyle &= (~WS_EX_TOPMOST); + + if (private->state & GDK_WINDOW_STATE_ABOVE) + exstyle |= WS_EX_TOPMOST; + + if (exstyle & WS_EX_TOPMOST) + top = HWND_TOPMOST; + else + top = HWND_TOP; + /* Use SetWindowPos to show transparent windows so automatic redraws * in other windows can be suppressed. */ - if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT) + if (exstyle & WS_EX_TRANSPARENT) { UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE; + if (!raise) flags |= SWP_NOZORDER; if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map) flags |= SWP_NOACTIVATE; - SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0, flags); + SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, flags); + return; } old_active_window = GetActiveWindow (); - if (private->state & (GDK_WINDOW_STATE_BELOW | GDK_WINDOW_STATE_ABOVE)) - { - DWORD exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE); - - if (private->state & GDK_WINDOW_STATE_BELOW) - exstyle &= (~WS_EX_TOPMOST); - if (private->state & GDK_WINDOW_STATE_ABOVE) - exstyle |= WS_EX_TOPMOST; - - API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window), GWL_EXSTYLE, exstyle)); - } - if (private->state & GDK_WINDOW_STATE_FULLSCREEN) { gdk_window_fullscreen (window); @@ -1140,10 +1145,14 @@ show_window_internal (GdkWindow *window, if (focus_on_map && private->accept_focus) { SetForegroundWindow (GDK_WINDOW_HWND (window)); + if (top == HWND_TOPMOST) + SetWindowPos (GDK_WINDOW_HWND (window), top, + 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } else { - SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP, + SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } -- 2.30.2